/*
时间片调度器使用例程
按以下步骤配置
1.配置定时器/滴答定时器周期，在定时器中断中填入api_ts_task_schedule()任务调度函数；
2.编写各任务函数主体；
3.初始化T_task_ts 任务列表，有几个任务列表内就有几个元素，初始化时配置ID、任务函数指针、任务时间片间隔、优先级；
4.调用api_ts_task_init()注册任务列表；
5.调用api_ts_task_start()开启调度器；
6.调用api_ts_task_exec()开始任务调度；

void task_1()
{
	static int i = 0;
	printf("this is task 1:%d\n",HAL_GetTick());
	if(i++ % 10 == 0)
	{
		api_ts_task_sleep(0,5000);
	}
}

void task_2()
{
	static int i = 0;
	int dlyMs = rand() % 10 + 1;
	printf("this is task 2:%d dly:%dms\n",HAL_GetTick(),dlyMs);
	HAL_Delay(dlyMs);
	if(i++ % 5 == 0)
	{
		api_ts_task_sleep(1,5000);
	}
}

void task_3()
{
	int dlyMs = rand() % 10 + 1;
	printf("this is task 3:%d dly:%dms\n",HAL_GetTick(),dlyMs);
	HAL_Delay(dlyMs);
}

void task_4()
{
	int dlyMs = rand() % 10 + 1;
	printf("this is task 4:%d dly:%dms\n",HAL_GetTick(),dlyMs);
	HAL_Delay(dlyMs);
}

T_task_ts task_list[] @0x20000000 = {
	{
		0,
		task_1,
		50,
		0
	},
	{
		1,
		task_2,
		50,
		1
	},
	{
		2,
		task_3,
		50,
		2
	},
	{
		3,
		task_4,
		50,
		3
	},
};

main(void)
{
	HAL_Init();

	SystemClock_Config();

	MX_GPIO_Init();
	MX_UART4_Init();

	api_ts_task_init(task_list,sizeof(task_list) / sizeof(task_list[0]));

	api_ts_start();

	api_ts_task_exec(); 
	
	while (1)
	{

		
	}
}

*/

#ifndef _TIMESLICE_H
#define _TIMESLICE_H

#include <stdint.h>

//定时器节拍时间/毫秒
#define TICK_PERIOD_MS          1

//毫秒转换为系统节拍
#define TS_MS2TICK(ms)          ( (ms >= TICK_PERIOD_MS) ? (ms / TICK_PERIOD_MS):1)
//系统节拍转换为毫秒
#define TS_TICK2MS(tick)        ( tick * TICK_PERIOD_MS)     

typedef enum{
    TS_INIT = 0,                //初始状态
    TS_STOP,                    //调度器暂停
    TS_RUN                      //调度器开启
}E_ts_status;                   //时间片调度的状态

typedef enum{
    TS_TASK_STOP = 0,           //不再执行 相当于删掉任务
    TS_TASK_RUN,                //执行中
    TS_TASK_READY,              //就绪
    TS_TASK_CNTDOWN,            //倒计时中
    TS_TASK_SLEEP               //睡眠中
}E_task_status;                 //单个任务的状态

typedef struct{
    //配置信息E_task_status;
    uint32_t    id;             //任务ID
    void        (*handle)(void);//任务句柄
    uint32_t    exec_period_ms; //执行周期 毫秒
    uint32_t    prority;        //优先级 0最高
    //运行信息
	uint32_t    exec_period;    //执行周期
    uint32_t    status;         //任务状态
    uint32_t    sleep_cntDown;  //任务休眠倒计时
    uint32_t    exec_cntDown;   //执行倒计时，自动重载为exec_period，倒计时至0运行
    uint32_t    exec_ready_wait_tick;//就绪态后等待运行的时间
	uint32_t    exec_total_time;//执行总时间 单位为TICK_PERIOD_MS
    uint32_t    exec_count;     //执行总次数
    uint32_t    exec_max_time;  //最长运行时间
    uint32_t    exec_min_time;  //最小运行时间
}T_task_ts;

void api_ts_start();                                                //开启时间片调度
void api_ts_stop();                                                 //关闭时间片调度
uint32_t api_ts_get_task_cnt();                                     //获取任务总数
uint32_t api_ts_get_ts_status();                                    //获取时间片调度器状态
uint32_t api_ts_getTick();                                          //获取调度器tick

void api_ts_task_init(T_task_ts *pTaskPool,uint32_t task_cnt);      //初始化各任务

void api_ts_task_start(uint32_t task_id);                           //开启某个任务
void api_ts_task_stop(uint32_t task_id);                            //停止某个任务
void api_ts_task_sleep(uint32_t task_id,uint32_t ms);               //休眠某个任务一定时间
void api_ts_task_schedule();                                        //时间片调度，在定时器节拍中调用
void api_ts_task_exec();                                            //任务执行
uint32_t api_ts_task_get_status(uint32_t task_id);                  //获取某个任务状态
uint32_t api_ts_getTick();

void hook_ts_idle_task();											//空闲任务钩子函数

#endif